package com.trt.ecommerce.util;

import com.alibaba.fastjson.JSON;
import com.trt.ecommerce.constant.CommonConstant;
import com.trt.ecommerce.vo.LoginUserInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import sun.misc.BASE64Decoder;

import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Calendar;

/**
 * @author tanrentao
 * @date 2021-08-18
 * @desc JWT Token 解析工具类（鉴权工具类）
 */
public class TokenParseUtil {

    /**
     * <h2>从JWT Token中解析LoginUserInfo对象</h2>
     **/
    public static LoginUserInfo parseUserInfoFromToken(String token) throws Exception {

        if (token == null) {
            return null;
        }

        Jws<Claims> claimsJwt = parseToken(token, getPublicKey());
        Claims body = claimsJwt.getBody();

        // 如果Token已经过期了,返回null
        if (body.getExpiration().before(Calendar.getInstance().getTime())) {
            return null;
        }

        // 返回Token 中保存的用户信息
        return JSON.parseObject(body.get(CommonConstant.JWT_USER_INFO_KEY).toString(), LoginUserInfo.class);

    }

    /**
     * <h2>通过公钥去解析JWT Token</h2>
     **/
    private static Jws<Claims> parseToken(String token, PublicKey publicKey) {

        return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
    }

    /**
     * <h2>根据本地存储的公钥获取到 PublicKey 对象</h2>
     **/
    private static PublicKey getPublicKey() throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(new BASE64Decoder().decodeBuffer(CommonConstant.PUBLIC_KEY));
        return KeyFactory.getInstance("RSA").generatePublic(keySpec);
    }

}
